home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / gfx / 3d / irit50src.lha / irit5 / grapdrvs / xgladap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-20  |  54.4 KB  |  1,526 lines

  1. /*****************************************************************************
  2. *   An SGI 4D driver using GL (experimental adaptive isocurve renderer.).    *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, June 1993.  *
  5. *****************************************************************************/
  6.  
  7. #include <gl/gl.h>
  8. #include <gl/device.h>
  9.  
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <math.h>
  13. #include <ctype.h>
  14. #include "irit_sm.h"
  15. #include "genmat.h"
  16. #include "config.h"
  17. #include "iritprsr.h"
  18. #include "allocate.h"
  19. #include "attribut.h"
  20. #include "ip_cnvrt.h"
  21. #include "cagd_lib.h"
  22. #include "symb_lib.h"
  23. #include "iritgrap.h"
  24.  
  25. /* Interactive menu setup structure: */
  26. #define INTERACT_NUM_OF_STRINGS        4
  27. #define INTERACT_NUM_OF_SUB_WNDWS    16
  28.  
  29. typedef struct InteractString {
  30.     RealType X, Y;
  31.     int Color;
  32.     char *Str;
  33. } InteractString;
  34. typedef struct InteractSubWindow {
  35.     RealType X, Y;                       /* Center points. */
  36.     int Color;
  37.     IGGraphicEventType Event;
  38.     int TextInside; /* If TRUE, Str will be in window, otherwise left to it. */
  39.     char *Str;
  40. } InteractSubWindow;
  41. typedef struct InteractWindowStruct {     /* The interactive menu structures. */
  42.     /* Rotate, Translate, Scale strings: */
  43.     InteractString Strings[INTERACT_NUM_OF_STRINGS];
  44.     InteractSubWindow SubWindows[INTERACT_NUM_OF_SUB_WNDWS];
  45. } InteractWindowStruct;
  46.  
  47. #define INTERACT_SUB_WINDOW_WIDTH  0.8         /* Relative to window size. */
  48. #define INTERACT_SUB_WINDOW_HEIGHT 0.04
  49.  
  50. static int
  51.     GlblStateMenu = 0,
  52.     GlblRuledSrfApprox = FALSE;
  53.  
  54. static long
  55.     TransWinID = 0,
  56.     TransWinWidth = 100,
  57.     TransWinWidth2 = 50,
  58.     TransWinHeight = 100,
  59.     TransWinLow = 0,
  60.     TransWinLeft = 0,
  61.     ViewWinID = 0,
  62.     ViewWinWidth = 100,
  63.     ViewWinWidth2 = 50,
  64.     ViewWinHeight = 100,
  65.     ViewWinHeight2 = 50,
  66.     ViewWinLow = 0,
  67.     ViewWinLeft = 0;
  68.  
  69. static RealType
  70.     GlblAdapIsoEps = 0.05,
  71.     GlblRuledSrfEps = 0.02;
  72.  
  73. /* Interactive mode menu set up structure is define below: */
  74. static InteractWindowStruct InteractMenu = {
  75.     { { 0.5, 0.81, IG_IRIT_RED,        "Rotate" },
  76.       { 0.5, 0.65, IG_IRIT_GREEN,    "Translate" },
  77.       { 0.5, 0.49, IG_IRIT_CYAN,    "Scale" },
  78.       { 0.5, 0.41, IG_IRIT_LIGHTGREEN,    "Clip Plane" },
  79.     },
  80.     { { 0.5, 0.93, IG_IRIT_YELLOW, IG_EVENT_SCR_OBJ_TGL,    TRUE,  "Screen Coords." },
  81.       { 0.5, 0.87, IG_IRIT_BLUE,   IG_EVENT_PERS_ORTHO_TGL,     TRUE,  "Perspective" },
  82.       { 0.5, 0.83, IG_IRIT_BLUE,   IG_EVENT_PERS_ORTHO_Z,    FALSE, "Z" },
  83.       { 0.5, 0.75, IG_IRIT_RED,    IG_EVENT_ROTATE_X,        FALSE, "X" }, /* Rot */
  84.       { 0.5, 0.71, IG_IRIT_RED,    IG_EVENT_ROTATE_Y,        FALSE, "Y" },
  85.       { 0.5, 0.67, IG_IRIT_RED,    IG_EVENT_ROTATE_Z,        FALSE, "Z" },
  86.       { 0.5, 0.59, IG_IRIT_GREEN,  IG_EVENT_TRANSLATE_X,    FALSE, "X" }, /* Trans */
  87.       { 0.5, 0.55, IG_IRIT_GREEN,  IG_EVENT_TRANSLATE_Y,    FALSE, "Y" },
  88.       { 0.5, 0.51, IG_IRIT_GREEN,  IG_EVENT_TRANSLATE_Z,    FALSE, "Z" },
  89.       { 0.5, 0.43, IG_IRIT_CYAN,   IG_EVENT_SCALE,        FALSE, "" },  /* Scale */
  90.       { 0.5, 0.35, IG_IRIT_LIGHTGREEN, IG_EVENT_NEAR_CLIP,    FALSE,  "" },
  91.       { 0.5, 0.31, IG_IRIT_LIGHTGREEN, IG_EVENT_FAR_CLIP,    FALSE,  "" },
  92.  
  93.       { 0.5, 0.20, IG_IRIT_YELLOW, IG_EVENT_SAVE_MATRIX,    TRUE,  "Save Matrix" },
  94.       { 0.5, 0.13, IG_IRIT_YELLOW, IG_EVENT_PUSH_MATRIX,    TRUE,  "Push Matrix" },
  95.       { 0.5, 0.09, IG_IRIT_YELLOW, IG_EVENT_POP_MATRIX,        TRUE,  "Pop Matrix" },
  96.       { 0.5, 0.03, IG_IRIT_WHITE,  IG_EVENT_QUIT,        TRUE,  "Quit" },
  97.     }
  98. };
  99.  
  100. static short Colors[IG_MAX_COLOR + 1][3] =
  101. {
  102.     { 0,   0,   0   },  /* 0. BLACK */
  103.     { 0,   0,   170 },  /* 1. BLUE */
  104.     { 0,   170, 0   },  /* 2. GREEN */
  105.     { 0,   170, 170 },  /* 3. CYAN */
  106.     { 170, 0,   0   },  /* 4. RED */
  107.     { 170, 0,   170 },  /* 5. MAGENTA */
  108.     { 170, 170, 0   },  /* 6. BROWN */
  109.     { 170, 170, 170 },  /* 7. LIGHTGREY */
  110.     { 85,  85,  85  },  /* 8. DARKGRAY */
  111.     { 85,  85,  255 },  /* 9. LIGHTBLUE */
  112.     { 85,  255, 85  },  /* 10. LIGHTGREEN */
  113.     { 85,  255, 255 },  /* 11. LIGHTCYAN */
  114.     { 255, 85,  85  },  /* 12. LIGHTRED */
  115.     { 255, 85,  255 },  /* 13. LIGHTMAGENTA */
  116.     { 255, 255, 85  },  /* 14. YELLOW */
  117.     { 255, 255, 255 }   /* 15. WHITE */
  118. };
  119.  
  120. static void IGDrawPolyNormal(IPObjectStruct *PObj, int HasNormals);
  121. static IPPolygonStruct *IritSurface2AdapIso(CagdSrfStruct *Srf,
  122.                         CagdSrfDirType Dir,
  123.                         RealType Eps,
  124.                         int SamplesPerCurve);
  125. static void SetColorIndex(int c);
  126. static void SetColorRGB(int Color[3]);
  127. static void ClearViewArea(void);
  128. static void SetTransformWindow(void);
  129. static void RedrawTransformWindow(void);
  130. static void SetViewWindow(void);
  131. static IGGraphicEventType GetGraphicEvent(RealType *ChangeFactor,
  132.                       int BlockForEvent);
  133. static void DrawText(char *Str, long PosX, long PosY);
  134.  
  135. /*****************************************************************************
  136. * DESCRIPTION:                                                               M
  137. * Main module of xgladap - Adaptive isocurve freeform surface rendering      M
  138. *               graphics driver of IRIT.                      M
  139. *                                                                            *
  140. * PARAMETERS:                                                                M
  141. *   argc, argv:  Command line.                                               M
  142. *                                                                            *
  143. * RETURN VALUE:                                                              M
  144. *   int:         Exit code.                                                  M
  145. *                                                                            *
  146. * KEYWORDS:                                                                  M
  147. *   main                                                                     M
  148. *****************************************************************************/
  149. void main(int argc, char **argv)
  150. {
  151.     RealType ChangeFactor;
  152.     IGGraphicEventType Event;
  153.  
  154.     IGConfigureGlobals("xgladap", argc, argv);
  155.  
  156.     SetViewWindow();
  157.     IGRedrawViewWindow();
  158.     SetTransformWindow();
  159.     RedrawTransformWindow();
  160.  
  161.     qdevice(LEFTMOUSE);
  162.     qdevice(MIDDLEMOUSE);
  163.     qdevice(RIGHTMOUSE);
  164.  
  165.     /* The default drawing window is the view window. */
  166.     winset(ViewWinID);
  167.  
  168.     setbell(1);                           /* Make it short. */
  169.  
  170.     IGCreateStateMenu();
  171.  
  172.     while ((Event = GetGraphicEvent(&ChangeFactor, TRUE)) != IG_EVENT_QUIT) {
  173.     if (IGProcessEvent(Event, ChangeFactor * IGGlblChangeFactor))
  174.         IGRedrawViewWindow();
  175.     }
  176. }
  177.  
  178. /*****************************************************************************
  179. * DESCRIPTION:                                                               M
  180. * Optionally construct a state pop up menu for the driver, if has one.       M
  181. *                                                                            *
  182. * PARAMETERS:                                                                M
  183. *   None                                                                     *
  184. *                                                                            *
  185. * RETURN VALUE:                                                              M
  186. *   void                                                                     M
  187. *                                                                            *
  188. * KEYWORDS:                                                                  M
  189. *   IGCreateStateMenu                                                        M
  190. *****************************************************************************/
  191. void IGCreateStateMenu(void)
  192. {
  193.     if (GlblStateMenu) 
  194.         freepup(GlblStateMenu);
  195.  
  196.     GlblStateMenu = newpup();
  197.  
  198.     addtopup(GlblStateMenu, " Set Up %t", 0);
  199.     addtopup(GlblStateMenu, "Oops!%l", 0);
  200.     addtopup(GlblStateMenu, "More Sensitive", 0);
  201.     addtopup(GlblStateMenu, "Less Sensitive%l", 0);
  202.     addtopup(GlblStateMenu, IGGlblTransformMode == IG_TRANS_SCREEN ?
  203.                 "Screen Trans." : "Object Trans", 0);
  204.     addtopup(GlblStateMenu, IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  205.                 "Perspective" : "Orthographic", 0);
  206.     addtopup(GlblStateMenu,
  207.          IGGlblDepthCue ? "Depth Cue" : "No Depth Cue", 0);
  208.     addtopup(GlblStateMenu,
  209.          IGGlblCacheGeom ? "Cache Geom" : "No Geom Cache", 0);
  210.     addtopup(GlblStateMenu,
  211.          IGGlblDrawSolid ? "Draw Solid" : "Draw Wireframe", 0);
  212.     addtopup(GlblStateMenu,
  213.          IGGlblBackFaceCull ? "Cull Back Face" : "No Cull Back Face", 0);
  214.     addtopup(GlblStateMenu,
  215.          IGGlblDoDoubleBuffer ? "Double Buffer" : "Single Buffer", 0);
  216.     addtopup(GlblStateMenu,
  217.          IGGlblAntiAliasing ? "Anti Aliasing" : "No Anti Aliasing", 0);
  218.     addtopup(GlblStateMenu,
  219.          IGGlblDrawInternal ? "Draw Internal Edges" : "No Internal Edges", 0);
  220.     addtopup(GlblStateMenu,
  221.          IGGlblDrawVNormal ? "Draw Vrtx Normals" :  "No Vrtx Normals", 0);
  222.     addtopup(GlblStateMenu,
  223.          IGGlblDrawPNormal ? "Draw Poly Normals" :  "No Poly Normals", 0);
  224.     addtopup(GlblStateMenu,
  225.          IGGlblDrawSurfaceMesh ? "Draw Surface Mesh" : "No Surface Mesh", 0);
  226.     addtopup(GlblStateMenu,
  227.          IGGlblDrawSurfacePoly ? "Surface Polygons" : "Surface Isolines", 0);
  228.     addtopup(GlblStateMenu,
  229.          IGGlblFourPerFlat ? "Four Per Flat%l" : "Two Per Flat%l", 0);
  230.     addtopup(GlblStateMenu, "More Isolines", 0);
  231.     addtopup(GlblStateMenu, "Less Isolines%l", 0);
  232.     addtopup(GlblStateMenu, "Finer Approx.", 0);
  233.     addtopup(GlblStateMenu, "Coarser Approx.%l", 0);
  234.     addtopup(GlblStateMenu, "Longer Vectors", 0);
  235.     addtopup(GlblStateMenu, "Shorter Vectors%l", 0);
  236.     addtopup(GlblStateMenu, "Wider Lines", 0);
  237.     addtopup(GlblStateMenu, "Narrow Lines%l", 0);
  238.     addtopup(GlblStateMenu, "Front View", 0);
  239.     addtopup(GlblStateMenu, "Side View", 0);
  240.     addtopup(GlblStateMenu, "Top View", 0);
  241.     addtopup(GlblStateMenu, "Isometry View%l", 0);
  242.     addtopup(GlblStateMenu, "Clear View Area%l", 0);
  243.     addtopup(GlblStateMenu, "Animation%l", 0);
  244.  
  245.     addtopup(GlblStateMenu, "Finer Adap. Iso.", 0);
  246.     addtopup(GlblStateMenu, "Coarser Adap. Iso.", 0);
  247.     addtopup(GlblStateMenu, "Finer Ruled Srf.", 0);
  248.     addtopup(GlblStateMenu, "Coarser Ruled Srf.", 0);
  249.     addtopup(GlblStateMenu, 
  250.          GlblRuledSrfApprox ? "Direct Adap. Iso." : "Ruled Adap. Iso.", 0);
  251.     addtopup(GlblStateMenu, "Adap. Iso. Dir.", 0);
  252. }
  253.  
  254. /*****************************************************************************
  255. * DESCRIPTION:                                                               M
  256. * Draw a single Point/Vector object using current modes and transformations. M
  257. *                                                                            *
  258. * PARAMETERS:                                                                M
  259. *   PObj:     A point/vector object to draw.                                 M
  260. *                                                                            *
  261. * RETURN VALUE:                                                              M
  262. *   void                                                                     M
  263. *                                                                            *
  264. * KEYWORDS:                                                                  M
  265. *   IGDrawPtVec                                                              M
  266. *****************************************************************************/
  267. void IGDrawPtVec(IPObjectStruct *PObj)
  268. {
  269.     static PointType
  270.     Zero = { 0.0, 0.0, 0.0 };
  271.     int i;
  272.     PointType Ends[6];
  273.     RealType
  274.     *Pt = PObj -> U.Pt;
  275.  
  276.     for (i = 0; i < 6; i++)
  277.     PT_COPY(Ends[i], Pt);
  278.  
  279.     Ends[0][0] -= IG_POINT_WIDTH;
  280.     Ends[1][0] += IG_POINT_WIDTH;
  281.     Ends[2][1] -= IG_POINT_WIDTH;
  282.     Ends[3][1] += IG_POINT_WIDTH;
  283.     Ends[4][2] -= IG_POINT_WIDTH;
  284.     Ends[5][2] += IG_POINT_WIDTH;
  285.  
  286.     for (i = 0; i < 6; i += 2) {
  287.     bgnline();
  288.     v3d(Ends[i]);
  289.     v3d(Ends[i+1]);
  290.     endline();
  291.     }
  292.  
  293.     if (IP_IS_VEC_OBJ(PObj)) {
  294.     bgnline();
  295.     v3d(Pt);
  296.     v3d(Zero);
  297.     endline();
  298.     }
  299. }
  300.  
  301. /*****************************************************************************
  302. * DESCRIPTION:                                                               M
  303. * Draw a single Poly object using current modes and transformations.         M
  304. *                                                                            *
  305. * PARAMETERS:                                                                M
  306. *   PObj:     A poly object to draw.                                         M
  307. *                                                                            *
  308. * RETURN VALUE:                                                              M
  309. *   void                                                                     M
  310. *                                                                            *
  311. * KEYWORDS:                                                                  M
  312. *   IGDrawPoly                                                               M
  313. *****************************************************************************/
  314. void IGDrawPoly(IPObjectStruct *PObj)
  315. {
  316.     IGDrawPolyNormal(PObj, FALSE);
  317. }
  318.  
  319. /*****************************************************************************
  320. * DESCRIPTION:                                                               *
  321. * Draw a single Poly object using current modes and transformations.         *
  322. *   This function allows polylines to have normals so we can actually draw   *
  323. * the adaptive isolines to render a surface.                     *
  324. *                                                                            *
  325. * PARAMETERS:                                                                *
  326. *   PObj:         A polygon or a polyline to draw.                           *
  327. *   HasNormals:   Do we have normal information included?                    *
  328. *                                                                            *
  329. * RETURN VALUE:                                                              *
  330. *   void                                                                     *
  331. *****************************************************************************/
  332. static void IGDrawPolyNormal(IPObjectStruct *PObj, int HasNormals)
  333. {
  334.     IPVertexStruct *V;
  335.     IPPolygonStruct
  336.     *Pl = PObj -> U.Pl;
  337.  
  338.     if (IP_IS_POLYLINE_OBJ(PObj)) {
  339.     for (; Pl != NULL; Pl = Pl -> Pnext) {
  340.         bgnline();
  341.         for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
  342.         if (HasNormals) {
  343.             float n[3];
  344.  
  345.             n[0] = V -> Normal[0];
  346.             n[1] = V -> Normal[1];
  347.             n[2] = V -> Normal[2];
  348.             n3f(n);
  349.         }
  350.             v3d(V -> Coord);
  351.         }
  352.         endline();
  353.     }
  354.     }
  355.     else if (IP_IS_POINTLIST_OBJ(PObj)) {
  356.     for (; Pl != NULL; Pl = Pl -> Pnext) {
  357.         for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
  358.         int i;
  359.         PointType Ends[6];
  360.         RealType
  361.             *Pt = V -> Coord;
  362.  
  363.         for (i = 0; i < 6; i++)
  364.             PT_COPY(Ends[i], Pt);
  365.  
  366.         Ends[0][0] -= IG_POINT_WIDTH;
  367.         Ends[1][0] += IG_POINT_WIDTH;
  368.         Ends[2][1] -= IG_POINT_WIDTH;
  369.         Ends[3][1] += IG_POINT_WIDTH;
  370.         Ends[4][2] -= IG_POINT_WIDTH;
  371.         Ends[5][2] += IG_POINT_WIDTH;
  372.  
  373.         for (i = 0; i < 6; i += 2) {
  374.             bgnline();
  375.             v3d(Ends[i]);
  376.             v3d(Ends[i+1]);
  377.             endline();
  378.         }
  379.         }
  380.     }
  381.     }
  382.     else if (IP_IS_POLYGON_OBJ(PObj)) {
  383.     int i, j,
  384.         NumOfVertices = 0;
  385.     PointType PNormal, VNormal;
  386.  
  387.     for (; Pl != NULL; Pl = Pl -> Pnext) {
  388.         if (IGGlblBackFaceCull) {
  389.             RealType P1[3], P2[3];
  390.  
  391.         MatMultVecby4by4(P1, Pl -> PVertex -> Coord,
  392.                  IritPrsrViewMat);
  393.         PT_ADD(PNormal, Pl -> PVertex -> Coord, Pl -> Plane);
  394.         MatMultVecby4by4(P2, PNormal, IritPrsrViewMat);
  395.         if (P2[2] - P1[2] > 0.0)
  396.             continue;
  397.         }
  398.  
  399.         if (IGGlblDrawPNormal) {
  400.         NumOfVertices = 0;
  401.         PNormal[0] = PNormal[1] = PNormal[2] = 0.0;
  402.         }
  403.  
  404.         if (IGGlblDrawSolid) {
  405.         bgnpolygon();
  406.         for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
  407.             float n[3];
  408.  
  409.             n[0] = V -> Normal[0];
  410.             n[1] = V -> Normal[1];
  411.             n[2] = V -> Normal[2];
  412.             n3f(n);
  413.             v3d(V -> Coord);
  414.  
  415.             if (IGGlblDrawPNormal) {
  416.             for (j = 0; j < 3; j++)
  417.                 PNormal[j] += V -> Coord[j];
  418.             NumOfVertices++;
  419.             }
  420.         }
  421.         endpolygon();
  422.         }
  423.         else {
  424.         bgnline();
  425.         for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
  426.             v3d(V -> Coord);
  427.             if (IP_IS_INTERNAL_VRTX(V) && !IGGlblDrawInternal) {
  428.             endline();
  429.             bgnline();
  430.             }
  431.  
  432.             if (IGGlblDrawPNormal) {
  433.             for (j = 0; j < 3; j++)
  434.                 PNormal[j] += V -> Coord[j];
  435.             NumOfVertices++;
  436.             }
  437.         }
  438.         v3d(Pl -> PVertex -> Coord);
  439.         endline();
  440.         }
  441.  
  442.         if (IGGlblDrawPNormal && IP_HAS_PLANE_POLY(Pl)) {
  443.         bgnline();
  444.         for (i = 0; i < 3; i++)
  445.             PNormal[i] /= NumOfVertices;
  446.         v3d(PNormal);
  447.         for (i = 0; i < 3; i++)
  448.             PNormal[i] += Pl -> Plane[i] * IGGlblNormalLen;
  449.         v3d(PNormal);
  450.         endline();
  451.         }
  452.  
  453.         if (IGGlblDrawVNormal) {
  454.         for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
  455.             if (IP_HAS_NORMAL_VRTX(V)) {
  456.             for (j = 0; j < 3; j++)
  457.                 VNormal[j] = V -> Coord[j] +
  458.                          V -> Normal[j] * IGGlblNormalLen;
  459.             bgnline();
  460.             v3d(V ->Coord);
  461.             v3d(VNormal);
  462.             endline();
  463.             }
  464.         }
  465.         }
  466.     }
  467.     }
  468. }
  469.  
  470. /*****************************************************************************
  471. * DESCRIPTION:                                                               M
  472. * Draw a single Surface object using current modes and transformations.         M
  473. *   Surface must be with either E3 or P3 point type and must be a NURB srf.  M
  474. *   Piecewise linear approximation is cashed under "_isoline" and "_ctlmesh" M
  475. * attributes of PObj. Adaptive isocurves are saved under "_adap_iso" and     M
  476. * polygons under "_polygons.".                             M
  477. *                                                                            *
  478. * PARAMETERS:                                                                M
  479. *   PObj:     A surface object to draw.                                      M
  480. *                                                                            *
  481. * RETURN VALUE:                                                              M
  482. *   void                                                                     M
  483. *                                                                            *
  484. * KEYWORDS:                                                                  M
  485. *   IGDrawSurface                                                            M
  486. *****************************************************************************/
  487. void IGDrawSurface(IPObjectStruct *PObj)
  488. {
  489.     IPObjectStruct *PObjPolylines, *PObjCtlMesh, *PObjPolygons;
  490.     IPPolygonStruct *PPolylines, *PCtlMesh, *PPolygons, *PPolyTemp;
  491.  
  492.     if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_isoline")) == NULL &&
  493.     IGGlblNumOfIsolines > 0) {
  494.     CagdSrfStruct *Srf,
  495.         *Srfs = PObj -> U.Srfs;
  496.  
  497.     PObjPolylines = IPAllocObject("", IP_OBJ_POLY, NULL);
  498.     PObjPolylines -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  499.     IP_SET_POLYLINE_OBJ(PObjPolylines);
  500.     for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
  501.         int NumOfIso[2];
  502.  
  503.         NumOfIso[0] = -IGGlblNumOfIsolines;
  504.         NumOfIso[1] = -IGGlblNumOfIsolines;
  505.         PPolylines = IritSurface2Polylines(Srf, NumOfIso,
  506.                            IGGlblSamplesPerCurve,
  507.                            IGGlblPolylineOptiApprox);
  508.  
  509.         if (PPolylines != NULL) {
  510.         for (PPolyTemp = PPolylines;
  511.              PPolyTemp -> Pnext;
  512.              PPolyTemp = PPolyTemp -> Pnext);
  513.         PPolyTemp -> Pnext = PObjPolylines -> U.Pl;
  514.         PObjPolylines -> U.Pl = PPolylines;
  515.         }
  516.     }
  517.     AttrSetObjectObjAttrib(PObj, "_isoline", PObjPolylines, FALSE);
  518.     }
  519.  
  520.     if (IGGlblDrawSolid) {
  521.     if (IGGlblDrawSurfacePoly) {
  522.         if ((PObjPolygons = AttrGetObjectObjAttrib(PObj, "_polygons"))
  523.                                     == NULL) {
  524.         CagdSrfStruct *Srf,
  525.             *Srfs = PObj -> U.Srfs;
  526.  
  527.         PObjPolygons = IPAllocObject("", IP_OBJ_POLY, NULL);
  528.         PObjPolygons -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  529.         IP_SET_POLYGON_OBJ(PObjPolygons);
  530.  
  531.         for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
  532.             PPolygons = IritSurface2Polygons(Srf, IGGlblFourPerFlat,
  533.                              IGGlblFineNess, FALSE,
  534.                              IGGlblPolygonOptiApprox);
  535.  
  536.             if (PPolygons != NULL) {
  537.             if (PPolygons) {
  538.                 for (PPolyTemp = PPolygons;
  539.                  PPolyTemp -> Pnext;
  540.                  PPolyTemp = PPolyTemp -> Pnext);
  541.                 PPolyTemp -> Pnext = PObjPolygons -> U.Pl;
  542.                 PObjPolygons -> U.Pl = PPolygons;
  543.             }
  544.             }
  545.         }
  546.         AttrSetObjectObjAttrib(PObj, "_polygons", PObjPolygons, FALSE);
  547.         }
  548.  
  549.         IGDrawPolyNormal(PObjPolygons, TRUE);
  550.     }
  551.     else {
  552.         if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_adap_iso"))
  553.                                     == NULL) {
  554.         CagdSrfStruct *Srf,
  555.             *Srfs = PObj -> U.Srfs;
  556.  
  557.         PObjPolylines = IPAllocObject("", IP_OBJ_POLY, NULL);
  558.         PObjPolylines -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  559.         IP_SET_POLYLINE_OBJ(PObjPolylines);
  560.  
  561.         for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
  562.             PPolylines = IritSurface2AdapIso(Srf, IGGlblAdapIsoDir,
  563.                              GlblAdapIsoEps,
  564.                              IGGlblSamplesPerCurve);
  565.  
  566.             if (PPolylines) {
  567.             for (PPolyTemp = PPolylines;
  568.                  PPolyTemp -> Pnext;
  569.                  PPolyTemp = PPolyTemp -> Pnext);
  570.             PPolyTemp -> Pnext = PObjPolylines -> U.Pl;
  571.             PObjPolylines -> U.Pl = PPolylines;
  572.             }
  573.         }
  574.         AttrSetObjectObjAttrib(PObj, "_adap_iso", PObjPolylines, FALSE);
  575.         }
  576.  
  577.         IGDrawPolyNormal(PObjPolylines, TRUE);
  578.     }
  579.     }
  580.     else
  581.         IGDrawPolyNormal(PObjPolylines, FALSE);
  582.  
  583.     if (IGGlblDrawSurfaceMesh) {
  584.     if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_ctlmesh"))
  585.                                 == NULL) {
  586.         CagdSrfStruct *Srf,
  587.         *Srfs = PObj -> U.Srfs;
  588.  
  589.         PObjCtlMesh = IPAllocObject("", IP_OBJ_POLY, NULL);
  590.         PObjCtlMesh -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  591.         IP_SET_POLYLINE_OBJ(PObjCtlMesh);
  592.         for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
  593.         PCtlMesh = IritSurface2CtlMesh(Srf);
  594.  
  595.         for (PPolyTemp = PCtlMesh;
  596.              PPolyTemp -> Pnext;
  597.              PPolyTemp = PPolyTemp -> Pnext);
  598.         PPolyTemp -> Pnext = PObjCtlMesh -> U.Pl;
  599.         PObjCtlMesh -> U.Pl = PCtlMesh;
  600.         }
  601.         AttrSetObjectObjAttrib(PObj, "_ctlmesh", PObjCtlMesh, FALSE);
  602.     }
  603.  
  604.     IGDrawPolyNormal(AttrGetObjectObjAttrib(PObj, "_ctlmesh"), FALSE);
  605.     }
  606. }
  607.  
  608. /*****************************************************************************
  609. * DESCRIPTION:                                                               *
  610. * Creates an adaptive isocurve coverage to a given surface.             *
  611. *                                                                            *
  612. * PARAMETERS:                                                                *
  613. *   Srf:                Surface to convert to adaptive isocurve's coverage.  *
  614. *   Dir:                Direction of isocurves. Either U or V.               *
  615. *   Eps:                Accuracy of coverage.                                *
  616. *   SamplesPerCurve:    Number of samples per isocurve.                      *
  617. *                                                                            *
  618. * RETURN VALUE:                                                              *
  619. *   IPPolygonStruct *:  A list of polylines approximating the coverage.      *
  620. *****************************************************************************/
  621. static IPPolygonStruct *IritSurface2AdapIso(CagdSrfStruct *Srf,
  622.                         CagdSrfDirType Dir,
  623.                         RealType Eps,
  624.                         int SamplesPerCurve)
  625. {
  626.     CagdCrvStruct *Coverage, *OneCoverage, *Crv;
  627.     IPPolygonStruct
  628.     *IsoPoly = NULL;
  629.     CagdSrfStruct *NSrf;
  630.  
  631.     if (Dir == CAGD_NO_DIR)
  632.     Dir = Srf -> UOrder == 2 ? CAGD_CONST_U_DIR : CAGD_CONST_V_DIR;
  633.  
  634.     fprintf(stderr, "Generating adaptive isocurve coverage...\n");
  635.     if (GlblRuledSrfApprox) {
  636.     int IsBspline = TRUE;
  637.     CagdSrfStruct *RuledSrfs, *NormalSrf, *TSrf;
  638.  
  639.     if (CAGD_IS_BEZIER_SRF(Srf)) {
  640.         IsBspline = FALSE;
  641.         Srf = CnvrtBezier2BsplineSrf(Srf);
  642.     }
  643.     RuledSrfs = SymbPiecewiseRuledSrfApprox(Srf, TRUE, GlblRuledSrfEps,
  644.                         Dir);
  645.  
  646.     Coverage = NULL;
  647.     NormalSrf = SymbSrfNormalSrf(Srf);
  648.     for (TSrf = RuledSrfs; TSrf != NULL; TSrf = TSrf -> Pnext) {
  649.         CagdRType UMin, UMax, VMin, VMax;
  650.  
  651.         CagdSrfDomain(TSrf, &UMin, &UMax, &VMin, &VMax);
  652.         if (Dir == CAGD_CONST_V_DIR)
  653.         NSrf = CagdSrfRegionFromSrf(NormalSrf, UMin, UMax,
  654.                         CAGD_CONST_U_DIR);
  655.         else
  656.         NSrf = CagdSrfRegionFromSrf(NormalSrf, VMin, VMax,
  657.                         CAGD_CONST_V_DIR);
  658.         OneCoverage = SymbAdapIsoExtract(TSrf, NSrf, NULL, Dir,
  659.                          Eps, FALSE, FALSE);
  660.         CagdSrfFree(NSrf);
  661.  
  662.         for (Crv = OneCoverage; Crv -> Pnext != NULL; Crv = Crv -> Pnext);
  663.         Crv -> Pnext = Coverage;
  664.         Coverage = OneCoverage;
  665.         fprintf(stderr, "Done with one ruled surface approximation.\n");
  666.     }
  667.     CagdSrfFreeList(RuledSrfs);
  668.     CagdSrfFree(NormalSrf);
  669.     if (!IsBspline)
  670.         CagdSrfFree(Srf);
  671.  
  672.     /* Scan the adaptive isoline list. Note that normal curve is paired */
  673.     /* after Euclidean curve, so we can step two curves at a time.      */
  674.     for (Crv = Coverage; Crv != NULL; Crv = Crv -> Pnext -> Pnext) {
  675.         CagdCrvStruct
  676.         *NCrv = Crv -> Pnext;
  677.         IPPolygonStruct
  678.         *Poly = IritCurve2Polylines(Crv, 1, IGGlblPolylineOptiApprox);
  679.  
  680.         if (Poly != NULL) {
  681.         RealType
  682.             *Nrml1 = Poly -> PVertex -> Normal,
  683.             *Nrml2 = Poly -> PVertex -> Pnext -> Normal;
  684.         CagdCoerceToE3(Nrml1, NCrv -> Points, 0, NCrv -> PType);
  685.         CagdCoerceToE3(Nrml2, NCrv -> Points, NCrv -> Length - 1,
  686.                    NCrv -> PType);
  687.         PT_NORMALIZE(Nrml1);
  688.         PT_SCALE(Nrml1, -1.0);
  689.         PT_NORMALIZE(Nrml2);
  690.         PT_SCALE(Nrml2, -1.0);
  691.  
  692.         Poly -> Pnext = IsoPoly;
  693.         IsoPoly = Poly;
  694.         }
  695.     }
  696.     }
  697.     else {
  698.     NSrf = SymbSrfNormalSrf(Srf);
  699.  
  700.     Coverage = SymbAdapIsoExtract(Srf, NSrf, NULL, Dir, Eps, FALSE, FALSE);
  701.         fprintf(stderr,
  702.             "Done with adaptive isocurve surface approximation.\n");
  703.  
  704.     CagdSrfFree(NSrf);
  705.  
  706.     /* Scan the adaptive isoline list. Note that normal curve is paired */
  707.     /* after Euclidean curve, so we can step two curves at a time.      */
  708.     for (Crv = Coverage; Crv != NULL; Crv = Crv -> Pnext -> Pnext) {
  709.         IPVertexStruct *VP, *VN;
  710.         IPPolygonStruct
  711.         *Poly = IritCurve2Polylines(Crv, IGGlblSamplesPerCurve,
  712.                         IGGlblPolylineOptiApprox),
  713.         *NPoly = IritCurve2Polylines(Crv -> Pnext,
  714.                          IGGlblSamplesPerCurve,
  715.                          IGGlblPolylineOptiApprox);
  716.  
  717.         if (Poly != NULL && NPoly != NULL) {
  718.         for (VP = Poly -> PVertex, VN = NPoly -> PVertex;
  719.              VP != NULL;
  720.              VP = VP -> Pnext, VN = VN -> Pnext) {
  721.             PT_COPY(VP -> Normal, VN -> Coord);
  722.             PT_NORMALIZE(VP -> Normal);
  723.             PT_SCALE(VP -> Normal, -1.0);
  724.         }
  725.  
  726.         IPFreePolygonList(NPoly);
  727.  
  728.         Poly -> Pnext = IsoPoly;
  729.         IsoPoly = Poly;
  730.         }
  731.     }
  732.     }
  733.  
  734.     CagdCrvFreeList(Coverage);
  735.  
  736.     return IsoPoly;    
  737. }
  738.  
  739. /*****************************************************************************
  740. * DESCRIPTION:                                                               M
  741. * Sets the color of an object according to its color/rgb attributes.         M
  742. *   If object has an RGB attribute it will be used. Otherwise, if the object M
  743. * has a COLOR attribute it will use. Otherwise, WHITE will be used.         M
  744. *                                                                            *
  745. * PARAMETERS:                                                                M
  746. *   PObj:      To set the drawing color to its color.                        M
  747. *                                                                            *
  748. * RETURN VALUE:                                                              M
  749. *   void                                                                     M
  750. *                                                                            *
  751. * KEYWORDS:                                                                  M
  752. *   IGSetColorObj                                                            M
  753. *****************************************************************************/
  754. void IGSetColorObj(IPObjectStruct *PObj)
  755. {
  756.     int c, Color[3];
  757.  
  758.     if (AttrGetObjectRGBColor(PObj, &Color[0], &Color[1], &Color[2])) {
  759.     SetColorRGB(Color);
  760.     }
  761.     else if ((c = AttrGetObjectColor(PObj)) != IP_ATTR_NO_COLOR) {
  762.     SetColorIndex(c);
  763.     }
  764.     else {
  765.     /* Use white as default color: */
  766.     SetColorIndex(IG_IRIT_WHITE);
  767.     }
  768. }
  769.  
  770. /*****************************************************************************
  771. * DESCRIPTION:                                                               M
  772. * Sets the line width to draw the given object, in pixels.             M
  773. *                                                                            *
  774. * PARAMETERS:                                                                M
  775. *   Width:    In pixels of lines to draw with.                               M
  776. *                                                                            *
  777. * RETURN VALUE:                                                              M
  778. *   void                                                                     M
  779. *                                                                            *
  780. * KEYWORDS:                                                                  M
  781. *   IGSetWidthObj                                                            M
  782. *****************************************************************************/
  783. void IGSetWidthObj(int Width)
  784. {
  785.     linewidth(Width);
  786. }
  787.  
  788. /*****************************************************************************
  789. * DESCRIPTION:                                                               *
  790. * Sets the color according to the given color index.                     *
  791. *                                                                            *
  792. * PARAMETERS:                                                                *
  793. *   color:     Index of color to use. Must be between 0 and IG_MAX_COLOR.    *
  794. *                                                                            *
  795. * RETURN VALUE:                                                              *
  796. *   void                                                                     *
  797. *****************************************************************************/
  798. static void SetColorIndex(int color)
  799. {
  800.     int Color[3];
  801.  
  802.     if (color < 0 || color > IG_MAX_COLOR)
  803.         color = IG_IRIT_WHITE;
  804.  
  805.     Color[0] = Colors[color][0];
  806.     Color[1] = Colors[color][1];
  807.     Color[2] = Colors[color][2];
  808.  
  809.     SetColorRGB(Color);
  810. }
  811.  
  812. /*****************************************************************************
  813. * DESCRIPTION:                                                               *
  814. * Sets the color according to the given RGB values.                 *
  815. *                                                                            *
  816. * PARAMETERS:                                                                *
  817. *   Color:      An RGB vector of integer values between 0 and 255.           *
  818. *                                                                            *
  819. * RETURN VALUE:                                                              *
  820. *   void                                                                     *
  821. *****************************************************************************/
  822. static void SetColorRGB(int Color[3])
  823. {
  824.     int i;
  825.     static float
  826.     Ambient = 0.25,
  827.     Diffuse = 0.75,
  828.     Specular = 1.0;
  829.     static float
  830.     Material[] = {
  831.         AMBIENT,  0.25, 0.25, 0.25,
  832.         DIFFUSE,  0.75, 0.75, 0.75,
  833.         SPECULAR, 1.00, 1.00, 1.00,
  834.         SHININESS, 50,
  835.         LMNULL
  836.     };
  837.  
  838.     c3i((long *) Color);
  839.     if (IGGlblDepthCue)
  840.     lRGBrange(0, 0, 0, Color[0], Color[1], Color[2], 0x0, 0x7fffff);
  841.  
  842.     /* Prepare material structure in this color and select it. */
  843.     for (i = 0; i < 3; i++) {
  844.     Material[1 + i] = Ambient * Color[i] / 255.0;
  845.     Material[5 + i] = Diffuse * Color[i] / 255.0;
  846.     Material[9 + i] = Specular * Color[i] / 255.0;
  847.     }
  848.     lmdef(DEFMATERIAL, 1, sizeof(Material) / sizeof(float), Material);
  849. }
  850.  
  851. /*****************************************************************************
  852. * DESCRIPTION:                                                               *
  853. * Sets up and draw a transformation window.                     *
  854. *                                                                            *
  855. * PARAMETERS:                                                                *
  856. *   none                                     *
  857. *                                                                            *
  858. * RETURN VALUE:                                                              *
  859. *   void                                                                     *
  860. *****************************************************************************/
  861. static void SetTransformWindow(void)
  862. {
  863.     long PrefPos[4];
  864.  
  865. #ifndef _AIX
  866.     foreground();
  867. #endif
  868.  
  869.     if (sscanf(IGGlblTransPrefPos, "%ld,%ld,%ld,%ld",
  870.            &PrefPos[0], &PrefPos[1], &PrefPos[2], &PrefPos[3]) == 4)
  871.     prefposition(PrefPos[0], PrefPos[1], PrefPos[2], PrefPos[3]);
  872.     else if (sscanf(IGGlblTransPrefPos, "%ld,%ld",
  873.             &PrefPos[0], &PrefPos[1]) == 2)
  874.     prefsize(PrefPos[0], PrefPos[1]);
  875.     winopen("Poly3dTrans");
  876.     winconstraints();
  877.     wintitle("xGLdrvs");
  878.     RGBmode();
  879.     gconfig();
  880.     getorigin(&TransWinLeft, &TransWinLow);
  881.     getsize(&TransWinWidth, &TransWinHeight);
  882.     TransWinWidth2 = TransWinWidth / 2;
  883.     TransWinID = winget();
  884.  
  885.     SetColorRGB(IGGlblBackGroundColor);
  886.     clear();
  887.  
  888.     /* This is wierd. without the sleep the gl get mixed up between the two  */
  889.     /* windows. If you have any idea why, let me know...             */
  890.     sleep(1);
  891. }
  892.  
  893. /*****************************************************************************
  894. * DESCRIPTION:                                                               M
  895. * Redraws the transformation window.                         M
  896. *                                                                            *
  897. * PARAMETERS:                                                                M
  898. *   None                                                                     M
  899. *                                                                            *
  900. * RETURN VALUE:                                                              M
  901. *   void                                                                     M
  902. *                                                                            *
  903. * KEYWORDS:                                                                  M
  904. *   RedrawTransformWindow                                                    M
  905. *****************************************************************************/
  906. static void RedrawTransformWindow(void)
  907. {
  908.     int i;
  909.     long SubTransPosX, SubTransPosY, SubTransWidth, SubTransHeight;
  910.  
  911.     /* Make sure the menu is consistent with internatal data. */
  912.     InteractMenu.SubWindows[0].Str =
  913.     IGGlblTransformMode == IG_TRANS_OBJECT ? "Object Coords."
  914.                          : "Screen Coords.";
  915.     InteractMenu.SubWindows[1].Str =
  916.     IGGlblViewMode == IG_VIEW_PERSPECTIVE ? "Perspective" : "Orthographic";
  917.  
  918.     winset(TransWinID);                /* Draw in the transformation window. */
  919.  
  920.     SubTransWidth = (int) (TransWinWidth * INTERACT_SUB_WINDOW_WIDTH);
  921.     SubTransHeight = (int) (TransWinHeight * INTERACT_SUB_WINDOW_HEIGHT);
  922.     SubTransPosX = (TransWinWidth - SubTransWidth) / 2;
  923.  
  924.     SetColorRGB(IGGlblBackGroundColor);
  925.     clear();
  926.  
  927.     for (i = 0; i < INTERACT_NUM_OF_SUB_WNDWS; i++) {
  928.     SetColorIndex(InteractMenu.SubWindows[i].Color);
  929.     SubTransPosY = (int) (TransWinHeight * InteractMenu.SubWindows[i].Y);
  930.  
  931.     move2i(SubTransPosX, SubTransPosY);
  932.     draw2i(SubTransPosX + SubTransWidth, SubTransPosY);
  933.     draw2i(SubTransPosX + SubTransWidth, SubTransPosY + SubTransHeight);
  934.     draw2i(SubTransPosX, SubTransPosY + SubTransHeight);
  935.     draw2i(SubTransPosX, SubTransPosY);
  936.     if (InteractMenu.SubWindows[i].TextInside) {
  937.         DrawText(InteractMenu.SubWindows[i].Str,
  938.              TransWinWidth / 2,
  939.              SubTransPosY + SubTransHeight / 2);
  940.     }
  941.     else {
  942.         DrawText(InteractMenu.SubWindows[i].Str,
  943.              (TransWinWidth - SubTransWidth) / 3,
  944.              SubTransPosY + SubTransHeight / 2);
  945.         move2i(SubTransPosX + SubTransWidth / 2, SubTransPosY);
  946.         draw2i(SubTransPosX + SubTransWidth / 2,
  947.            SubTransPosY + SubTransHeight);
  948.     }
  949.     }
  950.  
  951.     for (i = 0; i < INTERACT_NUM_OF_STRINGS; i++) {
  952.     SetColorIndex(InteractMenu.Strings[i].Color);
  953.     DrawText(InteractMenu.Strings[i].Str,
  954.          (int) (InteractMenu.Strings[i].X * TransWinWidth),
  955.          (int) (InteractMenu.Strings[i].Y * TransWinHeight));
  956.     }
  957.  
  958.     winset(ViewWinID);             /* Go back to the default drawing window. */
  959. }
  960.  
  961. /*****************************************************************************
  962. * DESCRIPTION:                                                               *
  963. * Clears the viewing area.                             *
  964. *                                                                            *
  965. * PARAMETERS:                                                                *
  966. *   None                                                                     *
  967. *                                                                            *
  968. * RETURN VALUE:                                                              *
  969. *   void                                                                     *
  970. *****************************************************************************/
  971. static void ClearViewArea(void)
  972. {
  973.     SetColorRGB(IGGlblBackGroundColor);
  974.     clear();
  975.     mmode(MVIEWING);
  976.     shademodel(GOURAUD);
  977.  
  978.     if (APX_EQ(IGGlblZMinClip, IGGlblZMaxClip))
  979.         IGGlblZMaxClip += EPSILON;
  980.     ortho(-1.0, 1.0, -1.0, 1.0, IGGlblZMinClip, IGGlblZMaxClip);
  981.  
  982.     if (winget() == ViewWinID) {
  983.     /* activate zbuffer only if we are in solid drawing mode. */
  984.     if (IGGlblDrawSolid) {
  985.         /* Define necessary staff for Lighting. */
  986.         lmbind(MATERIAL, 1);
  987.         lmbind(LMODEL, 1);
  988.         lmbind(LIGHT1, 1);
  989.  
  990.         zbuffer(TRUE);
  991.         zclear();
  992.     }
  993.     else {
  994.         zbuffer(FALSE);
  995.     }
  996.     }
  997. }
  998.  
  999. /*****************************************************************************
  1000. * DESCRIPTION:                                                               *
  1001. * Sets up a view window.                             *
  1002. *                                                                            *
  1003. * PARAMETERS:                                                                *
  1004. *   argc, argv:   Command line,                                              *
  1005. *                                                                            *
  1006. * RETURN VALUE:                                                              *
  1007. *   void                                                                     *
  1008. *                                                                            *
  1009. * KEYWORDS:                                                                  *
  1010. *   SetViewWindow                                                            *
  1011. *****************************************************************************/
  1012. static void SetViewWindow(void)
  1013. {
  1014.     long PrefPos[4];
  1015.     static int
  1016.     UpdateLightPos = FALSE;
  1017.     static float Light1[] = {
  1018.     AMBIENT, 0.25, 0.25, 0.25,
  1019.     POSITION, 0.1, 0.5, 1.0, 0.0,
  1020.     LMNULL
  1021.     };
  1022.  
  1023.     if (!UpdateLightPos) {
  1024.     int i;
  1025.  
  1026.     for (i = 0; i < 4; i++)
  1027.         Light1[i + 5] = IGGlblLightSrcPos[i];
  1028.  
  1029.     UpdateLightPos = TRUE;
  1030.     }
  1031.  
  1032. #ifndef _AIX
  1033.     foreground();
  1034. #endif
  1035.  
  1036.     if (sscanf(IGGlblViewPrefPos, "%ld,%ld,%ld,%ld",
  1037.            &PrefPos[0], &PrefPos[1], &PrefPos[2], &PrefPos[3]) == 4)
  1038.     prefposition(PrefPos[0], PrefPos[1], PrefPos[2], PrefPos[3]);
  1039.     else if (sscanf(IGGlblViewPrefPos, "%ld,%ld",
  1040.             &PrefPos[0], &PrefPos[1]) == 2)
  1041.     prefsize(PrefPos[0], PrefPos[1]);
  1042.     winopen("Poly3dView");
  1043.     winconstraints();
  1044.     wintitle("xGLdrvs");
  1045.     if (IGGlblDoDoubleBuffer)
  1046.     doublebuffer();
  1047.     else
  1048.         singlebuffer();
  1049.     RGBmode();
  1050.     if (IGGlblDepthCue) {
  1051. #    ifndef _AIX
  1052.         glcompat(GLC_ZRANGEMAP, 1);
  1053. #    endif /* _AIX */
  1054.     lRGBrange(0, 0, 0, 255, 255, 255, 0x0, 0x7fffff);
  1055.     depthcue(IGGlblDepthCue);
  1056.     }
  1057.     else
  1058.         depthcue(FALSE);
  1059.     if (IGGlblAntiAliasing) {
  1060. #    ifndef _AIX
  1061.         if (getgdesc(GD_PNTSMOOTH_CMODE) == 0 ||
  1062.         getgdesc(GD_BITS_NORM_DBL_CMODE) < 8)
  1063.         IGGlblAntiAliasing = FALSE;
  1064.         else {
  1065.         subpixel(TRUE);
  1066.         pntsmooth(SMP_ON);
  1067.         }
  1068. #    endif /* _AIX */
  1069.     }
  1070.     gconfig();
  1071.     getorigin(&ViewWinLeft, &ViewWinLow);
  1072.     getsize(&ViewWinWidth, &ViewWinHeight);
  1073.     ViewWinWidth2 = ViewWinWidth / 2;
  1074.     ViewWinHeight2 = ViewWinHeight / 2;
  1075.     
  1076.     ViewWinID = winget();
  1077.  
  1078.     concave(TRUE);
  1079.  
  1080.     /* Define necessary staff for Lighting. */
  1081.     lmdef(DEFMATERIAL, 1, 0, NULL);
  1082.     lmdef(DEFLMODEL, 1, 0, NULL);
  1083.     lmdef(DEFLIGHT, 1, sizeof(Light1) / sizeof(float), Light1);
  1084.  
  1085.     ClearViewArea();
  1086.     if (IGGlblDoDoubleBuffer)
  1087.     swapbuffers();
  1088.  
  1089.     /* This is wierd. without the sleep the gl get mixed up between the two  */
  1090.     /* windows. If you have any idea why, let me know...             */
  1091.     sleep(1);
  1092. }
  1093.  
  1094. /*****************************************************************************
  1095. * DESCRIPTION:                                                               M
  1096. * Redraw the view window.                                                    M
  1097. *                                                                            *
  1098. * PARAMETERS:                                                                M
  1099. *   None                                                                     M
  1100. *                                                                            *
  1101. * RETURN VALUE:                                                              M
  1102. *   void                                                                     M
  1103. *                                                                            *
  1104. * KEYWORDS:                                                                  M
  1105. *   IGRedrawViewWindow                                                       M
  1106. *****************************************************************************/
  1107. void IGRedrawViewWindow(void)
  1108. {
  1109.     IPObjectStruct *PObj, *MatObj;
  1110.     Matrix CrntView;
  1111.     int i, j;
  1112.     MatrixType IritCrntView, IritView;
  1113.  
  1114.     ClearViewArea();
  1115.  
  1116.     switch (IGGlblViewMode) {         /* Update the current view. */
  1117.     case IG_VIEW_ORTHOGRAPHIC:
  1118.         GEN_COPY(IritView, IritPrsrViewMat, sizeof(MatrixType));
  1119.         break;
  1120.     case IG_VIEW_PERSPECTIVE:
  1121.         MatMultTwo4by4(IritView, IritPrsrViewMat, IritPrsrPrspMat);
  1122.         break;
  1123.     }
  1124.  
  1125.     for (PObj = IGGlblDisplayList; PObj != NULL; PObj = PObj -> Pnext) {
  1126.     int Visible = TRUE;
  1127.  
  1128.     if ((MatObj = AttrGetObjectObjAttrib(PObj, "_animation_mat")) != NULL &&
  1129.         IP_IS_MAT_OBJ(MatObj)) {
  1130.         if (Visible = AttrGetObjectIntAttrib(PObj, "_isvisible")) {
  1131.         MatMultTwo4by4(IritCrntView,
  1132.                    *MatObj -> U.Mat, IritPrsrViewMat);
  1133.         if (IGGlblViewMode == IG_VIEW_PERSPECTIVE) 
  1134.             MatMultTwo4by4(IritCrntView,
  1135.                    IritCrntView, IritPrsrPrspMat);
  1136.         }
  1137.     }
  1138.     else
  1139.         GEN_COPY(IritCrntView, IritView, sizeof(MatrixType));
  1140.  
  1141.     if (Visible) {
  1142.         for (i = 0; i < 4; i++)
  1143.         for (j = 0; j < 4; j++)
  1144.             CrntView[i][j] = IritCrntView[i][j];
  1145.         loadmatrix(CrntView);
  1146.  
  1147.         IGDrawObject(PObj);
  1148.     }
  1149.     }
  1150.  
  1151.     if (IGGlblDoDoubleBuffer)
  1152.     swapbuffers();
  1153. }
  1154.  
  1155. /*****************************************************************************
  1156. * DESCRIPTION:                                                               *
  1157. * Handles input events                                                       *
  1158. *                                                                            *
  1159. * PARAMETERS:                                                                *
  1160. *   ChangeFactor:        A continuous numeric value between -1 and 1. This   *
  1161. *             value will be used to set amount of event such as   *
  1162. *             rotation or translation.                 *
  1163. *   BlockForEvent:     If TRUE, blocks until event is recieved.         *
  1164. *                                                                            *
  1165. * RETURN VALUE:                                                              *
  1166. *   IGGraphicEventType:  Type of new event.                                  *
  1167. *****************************************************************************/
  1168. static IGGraphicEventType GetGraphicEvent(RealType *ChangeFactor,
  1169.                       int BlockForEvent)
  1170. {
  1171.     static IGGraphicEventType
  1172.     LastEvent = IG_EVENT_NONE;
  1173.     static long
  1174.     LastX = -1;
  1175.     int i, TransformRequest,
  1176.         LeftButtonIsPressed = getbutton(LEFTMOUSE) == 1;
  1177.     IGGraphicEventType
  1178.     RetVal = IG_EVENT_NONE;
  1179.     short data;
  1180.     long y, dev,
  1181.     x = -1;
  1182.     RealType XPos, YPos;
  1183.  
  1184.     /* Allow continuous drag on following events only: */
  1185.     if (LeftButtonIsPressed && !IG_IS_DRAG_EVENT(LastEvent)) {
  1186.     while (getbutton(LEFTMOUSE) == 1);
  1187.     LeftButtonIsPressed = FALSE;
  1188.     }
  1189.  
  1190.     if (LeftButtonIsPressed) {
  1191.     /* Allow leaving the Trans window if still pressed, and use last     */
  1192.     /* event as the returned event.    Note we wait until current position  */
  1193.     /* is different from last one to make sure we do something.          */
  1194.     while((x = getvaluator(MOUSEX) - TransWinLeft) == LastX &&
  1195.           getbutton(LEFTMOUSE) == 1);
  1196.     if (x != LastX) {
  1197.         *ChangeFactor = (((RealType) x) - LastX) / TransWinWidth2;
  1198.         LastX = x;
  1199.         return LastEvent;
  1200.     }
  1201.     else
  1202.         LeftButtonIsPressed = FALSE;
  1203.     }
  1204.  
  1205.     LastEvent = IG_EVENT_NONE;
  1206.  
  1207.     while (RetVal == IG_EVENT_NONE) {
  1208.     /* Wait for left button to be pressed in the Trans window. Note this */
  1209.     /* is the loop we are going to cycle in idle time.             */
  1210.     for (TransformRequest = FALSE; !TransformRequest;) {
  1211.         x = getvaluator(MOUSEX);
  1212.         y = getvaluator(MOUSEY);
  1213.  
  1214.         if (qtest()) {                  /* Any external event occured? */
  1215.         switch (dev = qread(&data)) {
  1216.             case REDRAW:
  1217.             if (data == ViewWinID) {
  1218.                 getorigin(&ViewWinLeft, &ViewWinLow);
  1219.                 getsize(&ViewWinWidth, &ViewWinHeight);
  1220.                 ViewWinWidth2 = ViewWinWidth / 2;
  1221.                 ViewWinHeight2 = ViewWinHeight / 2;
  1222.                 reshapeviewport();
  1223.                 ortho2(-0.5, ViewWinWidth - 0.5,
  1224.                    -0.5, ViewWinHeight - 0.5);
  1225.                 IGRedrawViewWindow();
  1226.             }
  1227.             else if (data == TransWinID) {
  1228.                 winset(TransWinID);
  1229.                 getorigin(&TransWinLeft, &TransWinLow);
  1230.                 getsize(&TransWinWidth, &TransWinHeight);
  1231.                 reshapeviewport();
  1232.                 ortho2(-0.5, TransWinWidth - 0.5,
  1233.                    -0.5, TransWinHeight - 0.5);
  1234.                 TransWinWidth2 = TransWinWidth / 2;
  1235.                 RedrawTransformWindow();
  1236.                 winset(ViewWinID);
  1237.             }
  1238.             break;
  1239.             case RIGHTMOUSE:
  1240.             if (data &&
  1241.                 IGHandleState(dopup(GlblStateMenu), FALSE)) {
  1242.                 *ChangeFactor = 0.0;
  1243.                 return IG_EVENT_STATE;
  1244.             }
  1245.             break;
  1246.             case LEFTMOUSE:
  1247.             TransformRequest = data;
  1248.             break;
  1249.         }
  1250.         continue;
  1251.         }
  1252.  
  1253.         /* Maybe we have something in communication socket. */
  1254.         if (!IGGlblStandAlone &&
  1255.         IGReadObjectsFromSocket(IGGlblViewMode, &IGGlblDisplayList))
  1256.         IGRedrawViewWindow();
  1257.  
  1258.  
  1259.         if (BlockForEvent)
  1260.         IritSleep(10);           /* So we do not use all CPU on idle. */
  1261.         else
  1262.         break;
  1263.     }
  1264.  
  1265.     if (!TransformRequest && !BlockForEvent)
  1266.         return RetVal;
  1267.  
  1268.     x -= TransWinLeft;
  1269.     y -= TransWinLow;
  1270.  
  1271.     XPos = ((RealType) x) / TransWinWidth;
  1272.     YPos = ((RealType) y) / TransWinHeight;
  1273.  
  1274.     /* Make sure we are in bound in the X direction. */
  1275.     if (XPos < (1.0 - INTERACT_SUB_WINDOW_WIDTH) / 2.0 ||
  1276.         XPos > 1.0 - (1.0 - INTERACT_SUB_WINDOW_WIDTH) / 2.0)
  1277.         continue;
  1278.  
  1279.     /* Now search the sub window the event occured in. */
  1280.     for (i = 0; i < INTERACT_NUM_OF_SUB_WNDWS; i++) {
  1281.         if (InteractMenu.SubWindows[i].Y <= YPos &&
  1282.         InteractMenu.SubWindows[i].Y + INTERACT_SUB_WINDOW_HEIGHT >=
  1283.                                     YPos) {
  1284.         RetVal = InteractMenu.SubWindows[i].Event;
  1285.         break;
  1286.         }
  1287.     }
  1288.     if (i == INTERACT_NUM_OF_SUB_WNDWS)
  1289.         continue;
  1290.  
  1291.     /* Take care of special cases in which the window should be updated. */
  1292.     switch (RetVal) {
  1293.         case IG_EVENT_SCR_OBJ_TGL:
  1294.         IGGlblTransformMode = IGGlblTransformMode == IG_TRANS_OBJECT ?
  1295.                                  IG_TRANS_SCREEN :
  1296.                                  IG_TRANS_OBJECT;
  1297.         RedrawTransformWindow();
  1298.         break;
  1299.         case IG_EVENT_PERS_ORTHO_TGL:
  1300.             IGGlblViewMode = IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  1301.                            IG_VIEW_ORTHOGRAPHIC :
  1302.                            IG_VIEW_PERSPECTIVE;
  1303.         RedrawTransformWindow();
  1304.         break;
  1305.         default:
  1306.         break;
  1307.     }
  1308.  
  1309.     *ChangeFactor = (((RealType) x) - TransWinWidth2) / TransWinWidth2;
  1310.     }
  1311.  
  1312.     LastEvent = RetVal;
  1313.     LastX = x;
  1314.  
  1315.     return RetVal;
  1316. }
  1317.  
  1318. /*****************************************************************************
  1319. * DESCRIPTION:                                                               M
  1320. * Handles the events of the pop up window.                                   M
  1321. *                                                                            *
  1322. * PARAMETERS:                                                                M
  1323. *   State:      Event to handle.                                             M
  1324. *   Refresh:    Do we need to refresh the screen according to what we know   M
  1325. *        on entry.                             M
  1326. *                                                                            *
  1327. * RETURN VALUE:                                                              M
  1328. *   int:        TRUE, if we need to refresh the screen.                      M
  1329. *                                                                            *
  1330. * KEYWORDS:                                                                  M
  1331. *   IGHandleState                                                            M
  1332. *****************************************************************************/
  1333. int IGHandleState(int State, int Refresh)
  1334. {
  1335.     int UpdateView = TRUE;
  1336.  
  1337.     switch (State) {
  1338.     case IG_STATE_SCR_OBJ_TGL:
  1339.         IGGlblTransformMode = IGGlblTransformMode == IG_TRANS_OBJECT ?
  1340.                              IG_TRANS_SCREEN :
  1341.                              IG_TRANS_OBJECT;
  1342.         RedrawTransformWindow();
  1343.         UpdateView = FALSE;
  1344.         break;
  1345.     case IG_STATE_PERS_ORTHO_TGL:
  1346.         IGGlblViewMode = IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  1347.                            IG_VIEW_ORTHOGRAPHIC :
  1348.                            IG_VIEW_PERSPECTIVE;
  1349.         RedrawTransformWindow();
  1350.         break;
  1351.     case IG_STATE_DRAW_SOLID:
  1352.         IGGlblDrawSolid = !IGGlblDrawSolid;
  1353.         /* And fall thru to disable the depth cueing. */
  1354.         IGGlblDepthCue = TRUE; 
  1355.     case IG_STATE_DEPTH_CUE:
  1356.         IGGlblDepthCue = !IGGlblDepthCue;
  1357.         if (IGGlblDepthCue) {
  1358. #            ifndef _AIX
  1359.             glcompat(GLC_ZRANGEMAP, 1);
  1360. #            endif /* _AIX */
  1361.         lRGBrange(0, 0, 0, 255, 255, 255,
  1362.               0x0, 0x7fffff);
  1363.         depthcue(IGGlblDepthCue);
  1364.         }
  1365.         else
  1366.         depthcue(FALSE);
  1367.         break;
  1368.     case IG_STATE_DOUBLE_BUFFER:
  1369.         IGGlblDoDoubleBuffer = !IGGlblDoDoubleBuffer;
  1370.         winset(ViewWinID);
  1371.         if (IGGlblDoDoubleBuffer)
  1372.         doublebuffer();
  1373.         else
  1374.         singlebuffer();
  1375.         gconfig();
  1376.         break;
  1377.     case IG_STATE_ANTI_ALIASING:
  1378.         IGGlblAntiAliasing = !IGGlblAntiAliasing;
  1379. #        ifndef _AIX
  1380.         if (getgdesc(GD_PNTSMOOTH_CMODE) == 0 ||
  1381.             getgdesc(GD_BITS_NORM_DBL_CMODE) < 8)
  1382.             IGGlblAntiAliasing = FALSE;
  1383.         else
  1384.             subpixel(IGGlblAntiAliasing);
  1385. #        endif /* _AIX */
  1386.         break;
  1387.     case IG_STATE_FINER_APPROX:
  1388.         IGGlblSamplesPerCurve++;
  1389.         IGGlblFineNess++;
  1390.         IGActiveListFreeNamedAttribute("_polygons");
  1391.         IGActiveListFreeNamedAttribute("_adap_iso");
  1392.         IGActiveListFreeNamedAttribute("_isoline");
  1393.         break;
  1394.     case IG_STATE_COARSER_APPROX:
  1395.         IGGlblFineNess--;
  1396.         if (IGGlblFineNess < 2)
  1397.         IGGlblFineNess = 2;
  1398.         IGGlblSamplesPerCurve--;
  1399.         if (IGGlblSamplesPerCurve < 2)
  1400.         IGGlblSamplesPerCurve = 2;
  1401.         IGActiveListFreeNamedAttribute("_polygons");
  1402.         IGActiveListFreeNamedAttribute("_adap_iso");
  1403.         IGActiveListFreeNamedAttribute("_isoline");
  1404.         break;
  1405.     case IG_STATE_FINER_ADAP_ISO:
  1406.         GlblAdapIsoEps /= 2.0;
  1407.         IGActiveListFreeNamedAttribute("_adap_iso");
  1408.         break;
  1409.     case IG_STATE_COARSER_ADAP_ISO:
  1410.         GlblAdapIsoEps *= 2.0;
  1411.         IGActiveListFreeNamedAttribute("_adap_iso");
  1412.         break;
  1413.     case IG_STATE_FINER_RULED_SRF:
  1414.         GlblRuledSrfEps /= 2.0;
  1415.         IGActiveListFreeNamedAttribute("_adap_iso");
  1416.         break;
  1417.     case IG_STATE_COARSER_RULED_SRF:
  1418.         GlblRuledSrfEps *= 2.0;
  1419.         IGActiveListFreeNamedAttribute("_adap_iso");
  1420.         break;
  1421.     case IG_STATE_RULED_SRF_APPROX:
  1422.         GlblRuledSrfApprox = !GlblRuledSrfApprox;
  1423.         IGActiveListFreeNamedAttribute("_adap_iso");
  1424.         break;
  1425.     case IG_STATE_ADAP_ISO_DIR:
  1426.         if (IGGlblAdapIsoDir == CAGD_CONST_U_DIR)
  1427.         IGGlblAdapIsoDir = CAGD_CONST_V_DIR;
  1428.         else
  1429.         IGGlblAdapIsoDir = CAGD_CONST_U_DIR;
  1430.         IGActiveListFreeNamedAttribute("_adap_iso");
  1431.         break;
  1432.     default:
  1433.         UpdateView = IGDefaultStateHandler(State, Refresh);
  1434.     }
  1435.  
  1436.     if (Refresh && UpdateView)
  1437.     IGRedrawViewWindow();
  1438.  
  1439.     IGCreateStateMenu();
  1440.  
  1441.     return UpdateView;
  1442. }
  1443.  
  1444. /*****************************************************************************
  1445. * DESCRIPTION:                                                               *
  1446. * Draws text centered at the given position.                     *
  1447. *                                                                            *
  1448. * PARAMETERS:                                                                *
  1449. *   Str:        String to draw.                                              *
  1450. *   PosX, PosY: Location to draw at.                                         *
  1451. *                                                                            *
  1452. * RETURN VALUE:                                                              *
  1453. *   void                                                                     *
  1454. *****************************************************************************/
  1455. static void DrawText(char *Str, long PosX, long PosY)
  1456. {
  1457.     long Width = strwidth(Str);
  1458.  
  1459.     cmov2s(PosX - Width / 2, PosY - (getheight() / 2 - getdescender()));
  1460.     charstr(Str);
  1461. }
  1462.  
  1463. /*****************************************************************************
  1464. * DESCRIPTION:                                                               M
  1465. * Make some sound.                                                           M
  1466. *                                                                            *
  1467. * PARAMETERS:                                                                M
  1468. *   None                                                                     M
  1469. *                                                                            *
  1470. * RETURN VALUE:                                                              M
  1471. *   void                                                                     M
  1472. *                                                                            *
  1473. * KEYWORDS:                                                                  M
  1474. *   IGIritBeep                                                               M
  1475. *****************************************************************************/
  1476. void IGIritBeep(void)
  1477. {
  1478.     ringbell();
  1479. }
  1480.  
  1481. /*****************************************************************************
  1482. * DESCRIPTION:                                                               M
  1483. *   Should we stop this animation. Senses the event queue of X11.            M
  1484. *                                                                            *
  1485. * PARAMETERS:                                                                M
  1486. *   Anim:     The animation to abort.                                        M
  1487. *                                                                            *
  1488. * RETURN VALUE:                                                              M
  1489. *   int:      TRUE if we need to abort, FALSE otherwise.                     M
  1490. *                                                                            *
  1491. * KEYWORDS:                                                                  M
  1492. *   AnimCheckInterrupt                                                       M
  1493. *****************************************************************************/
  1494. int AnimCheckInterrupt(AnimationStruct *Anim)
  1495. {
  1496.     if (qtest()) {
  1497.     short data;
  1498.     Device
  1499.         dev = qread(&data);
  1500.  
  1501.     if (dev == RIGHTMOUSE) {
  1502.         fprintf(stderr, "\nAnimation was interrupted by the user.\n");
  1503.  
  1504.         Anim -> StopAnim = TRUE;
  1505.     }
  1506.     else if (dev == LEFTMOUSE) {
  1507.         IGGraphicEventType Event;
  1508.         RealType ChangeFactor;
  1509.  
  1510.         qenter(dev, data);
  1511.  
  1512.         winset(TransWinID);
  1513.         Event = GetGraphicEvent(&ChangeFactor, FALSE);
  1514.         winset(ViewWinID);
  1515.  
  1516.         if (Event != IG_EVENT_NONE) {
  1517.         if (IGProcessEvent(Event, ChangeFactor * IGGlblChangeFactor))
  1518.             IGRedrawViewWindow();
  1519.         }
  1520.  
  1521.     }
  1522.     }
  1523.  
  1524.     return Anim -> StopAnim;
  1525. }
  1526.